<template>
  <video v-preventright id="player" ref="player" class="video-js"/>
</template>

<script>
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
import { getToken } from '@/utils/auth'
import { encode } from '@/utils/aes'

// 获取加密数据
const getAuth = function() {
  // 强行凑16位
  const time = new Date().getTime()
  const data = encode(time)
  return encodeURIComponent(data)
}

//  全局拦截器
videojs.Vhs.xhr.beforeRequest = function(options) {
  if (options.uri.endsWith('decrypt')) {
    const headers = options.headers || {}
    headers['token'] = getToken()
    options.uri = `${options.uri}?auth=` + getAuth()
    options.headers = headers
  }
  return options
}

export default {
  name: 'VideoPlayer',
  props: {
    value: String,
    drag: Boolean
  },

  data() {
    return {
      player: null,
      duration: 0,
      options: {
        controls: true,
        loop: false,
        preload: true,
        aspectRatio: '16:9', // 显示比率
        fullscreen: {
          options: { navigationUI: 'hide' }
        },
        sources: [{
          src: '',
          type: 'video/mp4'
        }]
      },
      lastProc: 0
    }
  },

  watch: {
    value: {
      handler(val) {
        // 停止播放
        this.$emit('pause')
        // 构建视频信息
        this.fillVideo(val)
        // 手动修改地址
        this.player.src(this.options.sources)
        this.$nextTick(() => {
          this.$refs.player.load()
        })
      },
      deep: true
    }

  },
  mounted() {
    // 禁止下载
    if (this.$refs.player) {
      this.$refs.player.controlsList = 'nodownload'
    }
    this.initVideo()
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose()
    }
  },
  methods: {

    // 填充视频信息
    fillVideo(url) {
      // 清理
      this.lastProc = 0
      // 初始化播放地址
      this.options.sources[0].src = url
      // 媒体类型
      let videoType = 'video/mp4'
      // 支持m3u8
      if (/^.+(\.m3u8)$/.test(url)) {
        videoType = 'application/x-mpegURL'
      }
      this.options.sources[0].type = videoType
    },

    // 初始化播放器
    initVideo() {
      const that = this
      // 初始化视频播放信息
      this.fillVideo(this.value)

      // 初始化播放器
      this.player = videojs(this.$refs.player, this.options, function onPlayerReady() {
        this.on('loadedmetadata', function() {
          that.loaded(this)
        })
        // 保存进度
        this.on('timeupdate', function() {
          that.timeupdate(this)
        })
        this.on('play', function() {
          that.play()
        })
        this.on('ended', function() {
          that.ended(this)
        })
        this.on('pause', function() {
          console.log('pause....')
          that.$emit('pause')
        })
        this.on('contextmenu', function() {
          console.log('contextmenu....')
          return false
        })
      })
    },

    // 播放
    play() {
      console.log('playing....')
      this.$emit('play')
    },

    // 结束播放
    ended(v) {
      console.log('播放完成....')
      this.$emit('ended')
      // 设置重新开始
      setTimeout(() => {
        v.currentTime(0)
        this.lastProc = 0
      }, 1000)
      return false
    },

    // 视频加载完成
    loaded(v) {
      // 视频总长度
      this.duration = v.duration()
      // 发送长度
      this.$emit('loaded', this.duration)
    },

    // 进度变化
    timeupdate(v) {
      const curTime = v.currentTime()
      // 不能快进也不能后退
      if (this.drag && (curTime - this.lastProc > 2 || this.lastProc - curTime > 2)) {
        v.currentTime(this.lastProc)
        return
      }
      this.lastProc = curTime
      // 更新时间
      this.$emit('timeupdate', curTime)
    },

    // 暂停
    pause() {
      this.player.pause()
    },

    // 指定开始时间
    startAt(sec) {
      if (this.duration > sec) {
        this.lastProc = sec
        this.player.currentTime(sec)
      }
    }
  }
}
</script>

